On Functional Programming, Language Design, and Persistence
نویسنده
چکیده
ion is the process of separating properties of objects into two classes, one for details that are relevant to a given task and the other for those that are not. The purpose of this process is to provide some number of partial problem-speci c views of a given object, each one simpler than the complete view because it temporarily disregards inessential details. Whether or not some property of a given object is essential depends on the purpose, and only the composition of the partial views yields the complete object again. Disregarding inessential details is easily formalized by universal quanti cation (for all x $ no matter what x is) and is supported in programming languages in various forms (e.g., procedures and functions, but also modules, objects, classes, types, etc.). In brief, abstraction is our major tool to handle complexity, and the principle of abstraction demands language support for it. The principle of correspondence derives directly from Landin's work [Lan66], who pointed out that inconsistent rules for the introduction and use of names unnecessarily complicate the description of programming languages and mentioned that `any use of a user-coined name implicitly involves a functional relation'. To avoid irritating inconsistencies, a name introduced as a formal parameter (of a procedure or function) should correspond to a name introduced by a local declaration, meaning that the rules for using names should not depend on the way names have been introduced3. As for the civil rights of data objects, we follow the separation of languages into two parts, called common logical structure and problem-oriented specialities in [Lan66] or framework and changeable parts in [Bac78]. We do not require the problem-oriented specialities such as arithmetic operations to be de ned on all data types here4, but de ne the civil rights of data objects in programming languages as the right to participate in all services provided by the general language framework. The only such service explicitly required by the principles is abstraction; other examples include assignment to mutable variables, parameter passing, and inclusion in data structures. The principles are strongly correlated: abstraction, which is explicitly required as a civil right for all language objects, is usually provided by giving names to details that are to be abstracted away in a partial program view. The principle of correspondence, which explicitly deals with names, implicitly requires that every object that can be named by a declaration can also be passed as a parameter, partially overlapping with the principle of data type completeness. All these principles follow the general rule of `power through simplicity, simplicity through generality' (attributed to van Wijngaarden [vW63]), and we argue that they give a good approximation of some important aspects of purely functional programming languages: semantic uniformity, uncompromising support for abstraction, and no complex exceptions to restrict some language objects to second class status. Therefore, we propose to take the principles as a starting point when searching for a characterization of functional programming languages. The principles are not restricted to languages that support only functions as basic units of programming, which is a very welcome property because it means that the principles can also guide the design of extensions to functional languages. In the next section, we demonstrate that some starting set of language features (the changeable parts of the language design) can be embedded into a simple and general language framework by completing the language with respect to the principles. However, it is certainly possible to invent languages that are complete with respect to the principles but do not o er all of the virtues associated with purely functional programming languages. Additional soundness constraints (most likely including CRP and RT) are necessary to get a complete characterization of languages that carry the virtues of functional programming beyond the domain of functions. 3This correspondence may seem trivial to functional programmers, but see, e.g., Tennent's evaluation of Pascal [Ten77]. 4Although this approach might lead to interesting language designs, too. 7 4 The Principles Applied to Functional Language Design A Simple Functional Core Language To demonstrate the application of the three language design principles in the domain of functional programming languages, we informally introduce a simple functional language and evaluate it with respect to these principles. The language is basically an extended -calculus, including variables, multi-parameter abstractions and applications. The extensions comprise a construct to introduce collections of (mutually recursive) de nitions, arithmetic, relational, logical, and string operations5, and numbers, booleans and strings as basic data types. The (standard) reduction rules are omitted here. e = v j v1 : : : vn:e j (e0 e1 : : : en) j c j letrec v1 = e1 : : : vn = en in e0 c = number j boolean j string j arithOp j relOp j logicOp j stringOp Instead of viewing the language as an extended -calculus, we regard the syntactic category c as providing (representations for) the objects of interest (objects of basic data types and primitive functions on these objects). The -calculus then establishes the programming framework in which these problem-speci c features may be used. In particular, the framework provides the means for abstraction over these objects, and to each declarative form of abstraction (letrec), there is a corresponding parametric form (parameters of -abstractions). We could even omit the letrec, and de ne declarations directly through the correspondence to function applications (using x-point combinators to take care of recursion). The essential civil rights in this simple language relate to abstraction, which is allowed for all data objects. It is common to interpret -abstractions as programmer-de ned functions, so that the abstraction facility becomes a semantically meaningful object, too, and of course, abstraction over abstractions is also supported by the -calculus. These properties may not be surprising in themselves, but if we compare them with the inconsistencies found in the evaluation of Pascal [Ten77], or with the compromises made in the design of S-Algol [Mor79], we can conclude that the purely functional languages derived from the -calculus conform to the principles more strictly. This is not too surprising in hindsight: the approaches to programming language semantics from which the principles were derived mapped programs of conventional languages to expressions in (slightly modi ed) -calculi (e.g., [Lan65]). It does not necessarily follow that languages designed according to the principles tend to be functional in nature6, but we conjecture that languages that are complete with respect to the principles also share many of the virtues of functional languages. By introducing additional design constraints such as referential transparency or Church-Rosser property, the class of admissible language designs can be further restricted to exclude designs that would invalidate these properties. A Shift of Emphasis: Modular Programming We have already seen that the impact of the principles on the language design depends on the interpretation of the domain of discourse (for instance, we have included functions into our objects of interest, and we have been led to a higher-order language). To strengthen this point, we investigate the same language again with a slight shift of emphasis, motivated by the needs of programming practice: if programs get large, the original objects of discourse are no longer the only objects of interest. The programs themselves have to be seen as objects that need to be maintained, operated upon, and partitioned into understandable parts, which may then be combined in new ways to allow them to be reused. Reinvestigating the given language with this new emphasis on programs as objects, we see that the language is no longer complete with respect to the principles: large programs tend to include large numbers of de nitions, but collections of de nitions are not rst-class objects and no 5For legibility, we use in x notation for binary operations. 6Languages of other paradigms (logic, object-oriented) would need to be evaluated to settle this issue. 8 env : letrec env in e0 Figure 1: Abstraction over de nitions v1 = e1 ... vn = en Figure 2: Collections of de nitions as data objects defs :letrec v1 =... defs vn = in e0 Figure 3: Abstraction over right-hand sides e1 ...en Figure 4: Collections of expressions as data objects abstraction is allowed over the de nitions of a letrec. The obvious idea is to turn the de nition parts of letrec-constructs into rst-class data objects, to allow them to participate in abstractions, and to introduce some additional operations to modify and combine such rst-class variable environments. However, such an approach (illustrated in gures 1 and 2) would cut through the abstraction mechanism represented by letrec, allowing variable bindings to be introduced dynamically. Whether or not free variable occurrences in e0 are bound in env ( gure 1) would not be clear until the abstraction would eventually be applied to a dynamically constructed environment ( gure 2) that would then be substituted for env. We have boxed the variable name env and the collection of de nitions in this example to emphasize the meta-level character of these constructs: they would allow programmers to dynamically introduce the variable names abstracted over in the letrec-construct. As a consequence, the static scoping rule of the -calculus would be invalidated unless further constraints are introduced on the use of rst-class environments. Fortunately, there is a less dangerous way to complete the language. Instead of breaking the abstractions provided by a letrec, it su ces to turn the actual de nitions (i.e., the right hand sides of the de nition part) into a rst class object. Again, this is best demonstrated by an abstract example program (we still box pieces of code which are not valid in our language): The obvious representations of such collections of right-hand sides are data structures, and to facilitate the connection of individual de nitions to variable names, it is useful to choose data structures that allow access to their components by named, position-independent selectors. This description characterizes the necessary data structures as record-like, and so we add records to the language to represent collections of de nitions (using strings as selectors and an in x dot as selection operator). e = : : : j f s1 :: e1 : : : sn :: en g c = : : : j recordOp Binding of de nitions from a collection to variables with a local scope (corresponding to import from a module) is then simply accomplished by selection from a record ( gure 5), and export of de nitions from a local scope (de ning the export interface of a module) amounts to packaging the de nitions into a record ( gure 6). At this stage of the discussion, it may be helpful to associate our abstract example programs with some concrete application. For instance, the program in gure 6 could represent a module containing the de nitions of operations on lists (map, fold, . . . ), exporting all of them. The program in gure 5, if applied to the list module, would then import 9 r:letrec v1 = (r:\v1") ... vn = (r:\vn") in e0 Figure 5: Import of items from a module r letrec v1 = e1 ... vn = en in f \v1" :: v1 ... \vn" :: vn g Figure 6: Export of locally de ned items all of these list operations. The imported functions are bound to local identi ers and may be used in e0 as if they had been de ned locally. Of course, the speci cation of import and export could be alleviated by syntactic sugar, but for our current discussion, it is more important that abstraction is allowed over records, so that records may be used as function parameters and result values. In this way, collections of de nitions are given rst-class status without a ecting the static binding structure of the language. Adding records to the language also adds a new civil right, namely the right to be included as a component in a data structure, and by the principle of data type completeness, this right should be given to all data objects, including objects and operators of basic types as well as programmer-de ned functions and records. If these conditions are ful lled, our extended language is again complete with respect to the design principles, and if suitable operations are provided on records, it is well prepared for the problems of modular programming. An Extension: Interactions with Runtime Environments We have seen that our simple language is complete for programming with basic objects, operations and functions, and we have seen that it needs to be completed if programs get large enough so that collections of de nitions also become objects of interest. So far, the design principles and functional programming seem to correspond with each other nicely, and we can now turn to a simple extension of our completed language, using facilities for input/output as an example. Such facilities are needed to allow otherwise purely functional programs to interact with their runtime environments (comprising, e.g., le systems, terminals, other programs) and have attracted considerable interest in the past. First of all, we need to describe the objects of interest and choose representations for them. We could, for instance, take typical elements of runtime environments as objects, but we choose a more abstract approach here, taking interactions themselves as objects of interest without making explicit the environments with which programs interact. More precisely, we choose a simpli ed variant of monadic input/output [PJW93]. We restrict the discussion to two elementary interactions, get and put, which should su ce to establish a two-way communication, e.g., with a le system. get and put are parameterized with the name of the le they operate upon and return result values as parameters of an explicit return-interaction. Interactions can be composed using the binary operator >>=. Interaction descriptions are executed if they are returned as the result value of the whole program, i.e., if they are not embedded in any non-empty program context. Elementary interactions are executed in the order in which they appear in the interaction description. c = : : : j interactions interactions = return j >>= j get j put Following the principles of abstraction and data type completeness, interaction descriptions can be objects of abstraction and components of records. Since interactions are certainly a new 10 (put \module" letrec v1 = e1 ... vn = en in f \v1" :: v1 ... \vn" :: vn g) Figure 7: Storing a module in a le ((get \module") >>= m:letrec v1 = (m:\v1") ... vn = (m:\vn") in e0) Figure 8: Retrieving a module from a le general service provided by the extended language framework, all data objects (including basic objects and operations, functions, records, and interactions) should get the right to participate in interactions. This is a generalized view of interactions, at least if compared with the facilities for input/output provided in current functional languages (which usually allow only strings of characters as objects of interactions). The generalization is required by the design principles, and it simpli es the language design (by removing the restriction to character strings). To demonstrate that the generalization is also useful in practice, it su ces to take a second look at the issues of modular programming. Our extended programming language can not only be used as its own module language, the generalized interactions also allow (dynamically computed) modules to be shared with other programs. Modules may be stored permanently in the le system using put (cf. gure 7), and they may be retrieved from there using get (cf. gure 8). Again it may be helpful to consider a concrete instantiation of our abstract example programs. Figure 7 would then represent a snapshot of an interactive editing session in which, e.g., a list library is developed and tested, and evaluating the complete program would store the current version of the library in the le named \module". Evaluating the program in gure 8 would retrieve the current version of the list library from this le and then import the needed list operations as described for gure 5. The le system (or any other long-term storage used for program development) can then be integrated into the programming environment as a high-level module store, from which program components can be (dynamically) imported into other programs. Programmers no longer need to write conversion algorithms from and to strings if they want to store data objects permanently, and they do not need to descend to the operating system level for program construction. The module store supports the same high-level constructs as the programming language, any kind of object can be used as a program-building block, and program construction can be accomplished inside this language without any explicit reference to object les, linkers, loaders and other external formats and tools. The design principles tell us nothing about elementary interactions or about why it is necessary to restrict the execution of interaction descriptions to certain contexts. They do, however, con rm a basic idea of monadic input/output { to have an explicit representation of interactions as rstclass data objects. Furthermore, they tell us that most functional languages that provide facilities for input/output are incomplete. The incompleteness results from the restriction of interactions to strings of characters, and the negative e ects of this incompleteness can easily be demonstrated: the languages are complicated in that their rules for interactions contain exceptions (they are not valid if the object of interaction is not a string). Due to this restriction, these languages are also less expressive, and complex, tiresome, and error-prone conversion programs need to be written in order to communicate non-string objects (it might even be di cult to convert some objects into strings, e.g., functions). 11 5 Related Work Functional and Modular Programming Hughes [Hug90] argued that `modularity is the key to successful programming', and that `our ability to decompose a problem into parts depends directly on our ability to glue solutions together'. He emphasized the good support for modular programming in functional languages, focusing on higher-order functions and lazy evaluation as two important kinds of glue. While his main interest was to identify characteristic features of functional languages, Burstall and Lampson [BL84] also found strong relations between functional and modular programming when searching for a systematic treatment of `the linking together of a number of modules into a large program'. They proposed to view modular programming as functional programming with modules, hoping to `make \Programming in the Large" look very much like \Programming in the Small"'. We are now in a position to give a new explanation of the relation between modular programming and functional programming (cf. also [Rei97]). The key issue of modular programming is program complexity, and our major tool for dealing with complexity is abstraction. The language design principles demand explicit language support for abstraction, and both glues described by Hughes derive directly from the principles: to de ne higher-order functions, it is necessary to abstract away functions, and to pass functions as parameters, it is necessary for them to be rstclass data objects. Lazy evaluation is just an implementation technique, and the real glue is again abstraction, allowed over expressions irrespective of whether they have a normal form or not. Therefore, we propose to interpret applied -calculi not as calculi of functions extended with constants, but as functional languages completed with general abstraction facilities (supported by the -calculus part of the languages). Functional programming can then be described as modular programming with functions (building abstractions over functions), and we argue that the shift towards programming-in-the-large just involves abstractions over di erent basic units of programming (modules). Similarly, the means for abstraction available in languages derived from a -calculus can also be used to program in a modular style with other basic objects, such as interactions. From these views, we can also derive a new way to explain the virtues of functional programming to practical programmers: most advantages stem from the support for a uniform and general scheme of abstraction over whatever basic units of programming are necessary for a given problem domain. At least one characteristic of the functional paradigm is a modular style of programming, irrespective of program sizes and basic programming units. Persistence So far, we have described functional programming languages and their relation to semantic principles of language design, but the cautious reader may wonder whether we have forgotten the third part of the paper title, persistence. However, just because we have not explicitly mentioned persistence, it does not mean that it is not part of the exposition. On the contrary, we are convinced that, if the language design principles are accepted as partially characterizing functional languages, and if an extension of these languages with input/output is also considered necessary, there is simply no way around support for orthogonal persistence. We have purposely not mentioned this topic in our development of interactions, and only a few readers will have missed it: it has become common practice in (functional) language design to draw the borderline of language design right through the input/output facilities. Everything beyond this line is considered part of the operating system or programming environment and external to the language. As a consequence, complex and error-prone mappings between the high-level structures supported by the programming language and a subset of structures supported by both the language and the tools outside the language are necessary (this subset is usually the set of character strings). Apart from improvements in programming language design and a switch to the functional paradigm, this is essentially the same situation in which imperative languages were in the 1980s. It was in this situation when proposals for persistent programming were rst published 12 (e.g., [ABC+83]). The basic idea was that programming languages are supported by the verysame operating system mechanisms that are considered to support programming on the other sideof the input/output facilities. Therefore, it should be possible to support the same high-level con-structs in the programming language, in the external store, and in interactions between the two.Instead of having two fundamentally di erent worlds for programming and permanent storage(complex high-level structures in the programming language and sequences of character strings tocommunicate with the store), the two worlds could support the same level of abstraction. Com-plex translation algorithms for interactions would become super uous, and input/output would besimpli ed to operate on high-level language objects. The essence of interactions would then be tomove such objects between di erent contexts, some of which are temporary (a running program)and others are permanent (a persistent store), and the boundary between such contexts would bemuch less clear-cut than in current functional languages. For instance, persistence would be anorthogonal property of data objects, meaning that objects of all types (including functions) wouldhave the right to persist.Such stores that support persistent storage of high-level objects are not an illusion but havebeen built, and the persistence community has developed highly interesting integrated program-ming environments (cf. [AM95] for a recent survey). Persistence research has focused on the issuesof e cient implementations of persistent stores and on the interfaces between these stores and per-sistent programming languages. If we take into account that functional programming research hasfocused on the issues of programming language design and implementation (largely ignoring theissues of persistent storage and programming environments), it seems as if these two researchareas could form a perfect match. On the one hand, persistence research has also employed andextended the principles of language design given in section 3 [AM95, p. 8], and we have shownthat functional languages can conform to these principles more strictly than other languages. Onthe other hand, purely functional languages are still lacking sophisticated programming environ-ments, and while we have shown that generalized interactions allow us to use functional languagesas their own module languages in future designs, similar ideas have been explored in the persistencecommunity since 1984 (using imperative languages with rst-class procedures [AM84]).6 ConclusionsThe advantages of functional programming are well known in the research community and, aftera long time of isolation, purely functional languages seem to be prepared for the transition intopractice. On the one hand, the implementations and languages have been steadily improved {they cover their central topic well and also allow for interactions with external environments. Onthe other hand, the enduring insistence on using functional languages in university courses hasenlarged the potential user community. As a consequence, the number of practical programmersthat try to evaluate functional languages for their daily tasks is slowly increasing7, and the designof functional languages is also changing slowly in response to the practical experience.As any other change, this one brings chances and risks, and we have argued that it is moreimportant than ever to develop good characterizations of functional languages and of the virtuesof a functional programming style. If we fail to produce explicit representations of their implicitlywell-known advantages, an evaluation of functional languages with respect to their usability inpractice is di cult for outsiders. This prevents many practitioners from learning these languagesat all, and it provides no help to those that have made the learning e ort, but need to select theright tool for their next project. Furthermore, adequate characterizations are indispensable whenexisting functional languages are adapted to the needs of programmers (how can the characteristicproperties of these languages be retained if they are not even known)? In other words, without agood characterization of the virtues of functional programming, there is a high risk that functionallanguages leave these virtues behind when they move from their current research environment into7This is demonstrated by the increasing number of questions to this e ect in mailing-lists and UseNet newsgroupsdedicated to functional languages.13 practice, and it is almost sure that we cannot communicate the advantages of this programmingstyle to others.In an attempt to pin down some of the characteristics of functional languages, we have fo-cussed on their semantic simplicity. We have proposed using semantic principles as guidelines andyardsticks for the (re-)design of functional languages, and we have shown how these principlescan help to address some of the problems that occur when adapting functional languages to therequirements of practical programming projects. The principles have proven to be valuable in gen-erating simple (uniform) and general language designs from some starting set of language features,carrying much of the expressiveness of functional languages to other basic units of programming.However, conformance to the principles alone does not guarantee that a language has a simplebasis for formal reasoning. Strict conformance to the principles can therefore only be seen as anapproximation of a characterization of purely functional languages, and this approximation needsto be re ned with additional constraints (e.g., to ensure referential transparency).A second topic for future work is the impact of the design principles on language implemen-tations. Preliminary experience suggests that there are two opposite in uences: on the one hand,a simple and uniform language design can substantially simplify the implementation. On theother hand, existing implementations rely on (often unspeci ed) assumptions that are no longervalid for more general, completed languages. The second point can drastically complicate thetask of adapting existing implementations for generalized languages (to name but one example:the generalized interactions allow new program parts to be introduced into running programs,whereas implementations of current functional languages often assume that code fragments arestatic objects, completely known at program construction time and never modi ed or moved atruntime).Due to space limitations, the discussion had to be rather abstract here. Some of the designissues, in particular those of modular programming and input/output in functional languages, areinvestigated in more detail in [Rei97]. From our own experience, we are convinced that the majorachievements of functional programming research go far beyond `programming with functions',which is why we search for a di erent characterization. We try to separate the virtues of thefunctional paradigm from the use of functions as basic programming units in order to carry overthese virtues to programming with di erent basic objects (such as interactions or modules). Theexample design problems used in the present paper have deliberately been chosen to highlighttwo such areas. Records in combination with simple functional languages have been used sinceat least 1984 to model various abstractions for modular programming in theoretical accounts ofprogramming languages [CW85], and the correlation between rst-class procedures, persistenceand programming-in-the-large has been used in the persistence community for a similarly longperiod of time [AM84]. By taking advantage of such ideas, the functional community can increasethe potential of its programming paradigm for real-life applications.References[ABC+83] M.P. Atkinson, P.J. Bailey, K.J. Chisholm, W.P. Cockshott, and R. Morrison. AnApproach to Persistent Programming. Computer Journal, 4:360{365, 1983.[AM84] M. P. Atkinson and R. Morrison. Persistent First Class Procedures are Enough. volume181 of LNCS, pages 223{240. Springer, 1984.[AM95] M.P. Atkinson and R. Morrison. Orthogonally Persistent Object Systems. TechnicalReport FIDE/95/121, ESPRIT Basic Research Action, Project Number 6309|FIDE2,1995. Appeared in VLDB Journal, 4(3):319-401, 1995.[Bac78] J. Backus. Can Programming be Liberated from the von Neumann Style: A FunctionalStyle and Its Algebra of Programs. Communications of the ACM, 21(8):613{641, Au-gust 1978.14 [BD97] Hans-J. Boehm and Alan J. Demers. A garbage collector for C and C++.http://reality.sgi.com/employees/boehm_mti/gc.html, 1997.[BL84] R. Burstall and B. Lampson. A Kernel Language for Modules and Abstract DataTypes. Technical Report 1, September 1984. Also in `Semantics of Data Types',Springer LNCS 173; revised version appeared in Information and Computation, Vol.76, 1988.[CW85] Luca Cardelli and Peter Wegner. On Understanding Types, Data Abstraction, andPolymorphism. Computing Surveys, 17(4):471{522, December 1985.[GLSS76] Jr. Guy Lewis Steele and Gerald Jay Sussman. Lambda: The Ultimate Imperative. AIMemo 353, MIT AI laboratory, March 1976.[Han97] MichaelHanus.FunctionalLogicProgramming.http://www-i2.informatik.rwth-aachen.de/hanus/FLP/, 1997.[Has96] Report on the Programming Language Haskell A Non-strict, Purely Functional Lan-guage (Version 1.3). Technical report, Haskell comittee, May 1996.[HJ94] P. Hudak and M. P. Jones. Haskell vs. Ada vs. C++ vs. Awk vs. . . . An Experimentin Software Prototyping Productivity. Technical report, Yale, July 1994.[How97] Denis Howe.Free On-line Dictionary of Computing.http://wombat.doc.ic.ac.uk/foldoc/index.html, 1997.[Hud89] Paul Hudak. Conception, Evolution, and Application of Functional Programming Lan-guages. ACM Computing Surveys, 21(3):359{411, September 1989.[Hug90] John Hughes. Why functional programming matters. In Research Topics in FunctionalProgramming. Addison-Wesley, 1990.[Hut97] FrequentlyAskedQuestionsforcomp.lang.functional.http://www.cs.nott.ac.uk/Department/Staff/gmh/faq.html, August 1997.[ICF96] Proceedings of the ACM SIGPLAN '96 International Conference on Functional Pro-gramming (ICFP '96), May 24{26, 1996, volume 31(5) of ACM SIGPLAN Notices,New York, NY, USA, June 1996. ACM Press.[Jav95] Java Home Page. http://java.sun.com/, 1995.[Klu97] Werner Kluge, editor. Implementation of Functional Languages, 8th InternationalWorkshop, Bad Godesberg, Germany, September 1996, Selected Papers, number 1268in Lecture Notes in Computer Science. Springer Verlag, 1997.[Knu74] Donald E. Knuth. Structured Programming with go to Statements. ACM ComputingSurveys, 6(4):261{301, December 1974. (reprinted in [Was80]).[Lan65] P. J. Landin. A Correspondence Between ALGOL 60 and Church's Lambda-Notation:Parts I/II. Communications of the ACM, 8(2/3):89{101:158{165, February/March1965.[Lan66] P. J. Landin. The Next 700 Programming Languages. Communications of the ACM,9(3):157{166, March 1966.[Lea93] Gary T. Leavens. Introduction to the Literature On Programming Language Design.Technical Report TR 93-01b, Department of Computer Science, Iowa State University,January 1993. revised January 1994 and February 1996.15 [Loc97] Nikki Locke. Available C++ libraries FAQ. submitted to comp.lang.c++, also onlineat http://www.trmphrst.demon.co.uk/cpplibs1.html, 1997.[Mor79] Ronald Morrison. ON THE DEVELOPMENT OF ALGOL. PhD thesis, Departmentof Computational Science, University of St Andrews, December 1979.[MT91] Robin Milner and Mads Tofte. Commentary on Standard ML. MIT, 1991. ISBN0-262-63137-7.[MTH90] Robin Milner, Mads Tofte, and Robert Harper. The De nition of Standard ML. MIT,1990. ISBN 0-262-63132-6.[PJW93] S. L. Peyton Jones and P. Wadler. Imperative Functional Programming. In Proc. 20thSymp. on Principles of Programming Languages. ACM, January 1993.[PvE97] Rinus Plasmeijer and Marko van Eekelen. The Concurrent Clean Language Report{ version 1.2 (draft). Technical report, HILT { High Level Software Tools B.V. andUniversity of Nijmegen, March 1997.[Rei97] Claus Reinke. Functions, Frames, and Interactions { completing a -calculus-basedpurely functional language with respect to programming-in-the-large and interactionswith runtime environments. PhD thesis, submitted to the Faculty of Engineering,University of Kiel, August 1997.[Sto77] Joseph E. Stoy. Denotational Semantics: The Scott-Strachey Approach to ProgrammingLanguage Theory. The MIT Press, 1977.[Str72] Christopher Strachey. Varieties of Programming Language. In International ComputingSymposium, pages 222{233, 1972. also as: Technical Monograph PRG-10, Program-ming Research Group, Oxford, 1973.[Ten77] R. D. Tennent. Language Design Methods Based on Semantic Principles. Acta Infor-matica, 8:97{112, 1977.[vW63] Adriaan van Wijngaarden. Generalized ALGOL. In Richard Goodman, editor, AnnualReview in Automatic Programming, Vol. 3, pages 17{26. Pergamon Press, Oxford,1963.[Was80] Anthony I. Wasserman. TUTORIAL Programming Language Design. IEEE ComputerSociety Press, Los Alamitos, Calif., 1980. Initally presented at Compsac80, The IEEEComputer Society's Fourth International Computer Software & Applications Confer-ence, October 27-31, 1980. IEEE catalog no.: EHO 164-4.
منابع مشابه
Functional Hypersheets ( Extended
This paper introduces hypersheets, an extension of conventional programming language modules. Whereas modules are static, and usually textually based, hypersheets constitute a local or distributed network of hyperlinks::dynamically evolving links to either values or definitions. Hypersheets integrate notions of persistence, hyperprogramming and user interface design. In the purely functional co...
متن کاملDesign Issues for Persistent Java: A Type-Safe, Object-Oriented, Orthogonally Persistent System
The object-oriented programming language Java is receiving much attention and is likely to become a popular commercial programming language because of its regular structure, safety features and modern constructs. It presents a novel opportunity, because of this safety and potential popularity, to make orthogonal persistence defined by reachability widely available. We report on a design for a s...
متن کاملPersistent Languages and Architectures
Persistent programming is concerned with creating and manipulating data in a manner that is independent of its lifetime. The persistence abstraction yields a number of advantages in terms of orthogonal design and programmer productivity. One major advantage is that the abstraction integrates the database view of information with the programming language view. For this reason persistent programm...
متن کاملRationale for the Design of Persistence and Query Processing Facilities in the Database Programming Language O++
ODE is a database system and environment based on the object paradigm. It offers one integrated data model for both database and general purpose manipulation. The database is defined, queried, and manipulated in the database programming language O++, an extension of C++. O++ uses the C++ object definition facility, called the class, to provide data encapsulation and multiple inheritance. O++ ex...
متن کاملA Framework Based on Design Patterns for Providing Persistence in Object-Oriented Programming Languages
This paper describes an approach to providing object persistence in object-oriented programming languages without modifying the run-time system or the language itself. By successively applying design patterns such as the Serializer, Factory Method, and Strategy patterns we develop an object-oriented framework for providing object persistence. The advantages of object-orientation are highlighted...
متن کاملAnswer Set Application Programming: a Case Study on Tetris
Answer-Set Programming (ASP) is a successful branch of the logic programming paradigm with many applications in modelling and solving of NP-hard problems. Combinatorial problems are the main application domain of ASP and it seems unsuitable for serving as a programming language for interactive applications. However, we conjecture that there is no theoretical obstacle for using ASP to that end. ...
متن کامل